package cc.wanforme.st.server.authen.service;

import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.jaas.JaasGrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Service;

import cc.wanforme.st.server.authen.dto.AdminRoleAuth;
import cc.wanforme.st.server.authen.dto.UserRoleAuth;
import cc.wanforme.st.server.base.entity.RolePermission;
import cc.wanforme.st.server.base.entity.User;
import cc.wanforme.st.server.base.entity.UserRole;
import cc.wanforme.st.server.base.entity.Admin;
import cc.wanforme.st.server.base.entity.AdminRole;

/** 角色授权和认证
 * @author wanne
 * 2020年10月23日
 */
@Service
public class AuthService {

	/** 添加验证信息*/
	public void setAuthentications(AdminRoleAuth roleAuth) {
		Set<SimpleGrantedAuthority> authorities = new TreeSet<>(Comparator.comparing(sga -> sga.getAuthority()));
		
		Iterator<Entry<AdminRole, List<RolePermission>>> iterator = roleAuth.getRoleAuth().entrySet().iterator();
		while (iterator.hasNext()) {
			Entry<AdminRole, List<RolePermission>> entry = iterator.next();
			
			// 每个权限当作一个角色
			List<SimpleGrantedAuthority> tempAuth = entry.getValue().stream()
					.map(RolePermission::getPermission)
					.map(SimpleGrantedAuthority::new)
					.collect(Collectors.toList());
			
//			tempAuth.add(new SimpleGrantedAuthority("ROLE_USER"));
			
			authorities.addAll(tempAuth);
		}
		
		// 设置授权信息
		Admin admin = new Admin();
		BeanUtils.copyProperties(roleAuth.getAdmin(), admin, "password");
		String password = admin.getPassword();
		
		UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(admin, password, authorities);
		SecurityContextHolder.getContext().setAuthentication(upat);
	}
	
	/** 添加验证信息*/
	public void setAuthentications(UserRoleAuth roleAuth) {
		Set<SimpleGrantedAuthority> authorities = new TreeSet<>(Comparator.comparing(sga -> sga.getAuthority()));
		
		Iterator<Entry<UserRole, List<RolePermission>>> iterator = roleAuth.getRoleAuth().entrySet().iterator();
		while (iterator.hasNext()) {
			Entry<UserRole, List<RolePermission>> entry = iterator.next();
			
			// 每个权限当作一个角色
			List<SimpleGrantedAuthority> tempAuth = entry.getValue().stream()
					.map(RolePermission::getPermission)
					.map(SimpleGrantedAuthority::new)
					.collect(Collectors.toList());
			
//			tempAuth.add(new SimpleGrantedAuthority("ROLE_USER"));
			
			authorities.addAll(tempAuth);
		}
		
		// 设置授权信息
		User user = new User();
		BeanUtils.copyProperties(roleAuth.getUser(), user, "password");
		String password = user.getPassword();
		
		UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(user, password, authorities);
		SecurityContextHolder.getContext().setAuthentication(upat);
	}
	
	/** 添加验证信息 (角色必须唯一) */
	public void setAuthenticationsError(AdminRoleAuth roleAuth) {
		Set<JaasGrantedAuthority> authorities = new TreeSet<>(Comparator.comparing(sga -> sga.getAuthority()));
		String principal = roleAuth.getAdmin().getUsername();
		String credentials = roleAuth.getAdmin().getPassword();
		
		Iterator<Entry<AdminRole, List<RolePermission>>> iterator = roleAuth.getRoleAuth().entrySet().iterator();
		while (iterator.hasNext()) {
			Entry<AdminRole, List<RolePermission>> entry = iterator.next();
			String role = entry.getKey().getRole();
			
			// 每个权限当作一个角色
			List<SimpleGrantedAuthority> roleAuthorities = entry.getValue().stream()
					.map(RolePermission::getPermission)
					.map(SimpleGrantedAuthority::new)
					.collect(Collectors.toList());
			
			JaasGrantedAuthority jaasGA = new JaasGrantedAuthority(role,
					new PreAuthenticatedAuthenticationToken(principal, credentials, roleAuthorities));
			authorities.add(jaasGA);
			
			// 角色必须唯一，只执行一次
//			break;
		}
		
		// 设置授权信息
		UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(principal, credentials, authorities);
//		PreAuthenticatedAuthenticationToken upat = new PreAuthenticatedAuthenticationToken(principal, credentials, authorities);
		SecurityContextHolder.getContext().setAuthentication(upat);
	}

	
	/** 检查是否已经添加了验证信息
	 * @return
	 */
	public boolean isAuthenticated(){
		return SecurityContextHolder.getContext().getAuthentication() != null;
	}
	
}
